# -*- coding: iso-8859-1 -*-
########## models.py #############
import datetime

from django.db import models
from django.db.models import Q
from django.contrib.contenttypes.models import ContentType
from django.forms.widgets import *
from django.contrib.auth.models import *
from django.core.mail import send_mail, BadHeaderError
from django.template import Context, Template, loader
from django.core import mail
from django.contrib.contenttypes import generic
from django.conf import settings

from emailBackend import *

def general_account():
    a = Account(email=settings.DEFAULT_FROM_EMAIL, 
            host=settings.EMAIL_HOST, username=settings.EMAIL_HOST_USER,
            password=settings.EMAIL_HOST_PASSWORD
            )
    return a

class Account(models.Model):
    email = models.EmailField(max_length = 100)
    from_name = models.CharField(max_length = 100, null=True, blank=True)
    username = models.CharField(max_length = 100)
    password = models.CharField(max_length = 100)
    host = models.CharField(max_length = 100)
    max_num_of_messages = models.IntegerField(blank=True, null=True)
    num_of_messages_sent = models.IntegerField(default=0, blank=True, null=True)
    date_last_message = models.DateField(blank=True, null=True)

    def create_connection(self):
        connection = EmailBackend(host=self.host, username=self.username, password=self.password)
        self.connection = connection

    def get_connection(self):
        try:
            return self.connection
        except:
            self.create_connection()
            return self.connection

    def send_mail(self, message):
        if message.is_suscribed():
            connection = self.get_connection()
            if self.from_name:
                _from = "%s <%s>" % (self.from_name, self.email)
            else:
                _from = self.email
            email = mail.EmailMessage(message.subject, message.body, _from, [message.to])
            email.content_subtype = "html"
            connection.send_messages([email])
            self.set_num_of_messages_sent()

    def set_num_of_messages_sent(self):
        if self.date_last_message == datetime.date.today():
            self.num_of_messages_sent = self.num_of_messages_sent +1
        else:
            self.date_last_message = datetime.date.today()
            self.num_of_messages_sent = 1
        self.save()

    def should_send(self):
        return not(self.date_last_message == datetime.date.today() and self.num_of_messages_sent >= self.max_num_of_messages)

    def __unicode__(self):
        return self.email


class Communication(models.Model):
    name = models.CharField(max_length=100)
    subject = models.CharField(max_length=100)
    email = models.CharField(max_length=100)
    model = models.ForeignKey(ContentType, null=True, blank=True)
    queryset = models.CharField(max_length=100, null=True, blank=True)
    condition = models.CharField(max_length = 100, null = True, blank=True)
    template = models.TextField(null = True, blank=True)
    resend_every = models.IntegerField(default=0, blank=True, null=True, help_text="Reenviar cada cuantos dias")
    max_times = models.IntegerField(default=1, blank=True, null=True, help_text="Maxima cantidad de veces a reenviar para cada instancia (0 = ilimitado)")

    auto = models.BooleanField()
    account = models.ForeignKey(Account, related_name="communications")

    def get_instances(self):
        manager = self.model.model_class().objects
        if self.queryset:
            instances = eval("manager." + self.queryset)
        else:
            instances = manager.all()

        self.instances = []
        for instance in instances:
            if self.condition:
                f = eval(self.condition)
            else:
                f = True
            if f:
                m = Message.objects.filter(communication=self, instance_id=instance.id)
                f = f and (self.max_times == 0 or len(m) < self.max_times)
                f = f and (len(m) == 0 or (datetime.datetime.now() - m[len(m)-1].date).days >= self.resend_every)
            if f:
                self.instances.append(instance)

        return self.instances

    def get_message(self, instance):
        message = Message()
        message.communication = self
        if instance:
            message.instance_object = instance
        if not "@" in self.email:
            message.to = eval('instance.' + self.email)
        else:
            message.to = self.email
        message.subject = self.subject
        message.set_template(self.template)
        return message

    def send_all(self):
        if self.model:
            self.get_instances()
        else:
            self.instances = [None]
        self.account.create_connection()
        num_msgs_sent = 0
        for instance in self.instances:
            message = self.get_message(instance)
            message.sent = True
            message.save()
            self.account.send_mail(message)
            num_msgs_sent = num_msgs_sent +1
        return num_msgs_sent

    def __unicode__(self):
        return self.name
        

class Message(models.Model):
    communication = models.ForeignKey(Communication, related_name="messages", null=True, blank=True)

    date = models.DateTimeField(auto_now=True, blank=True, null=True)
    sent = models.BooleanField()

    instance_type = models.ForeignKey(ContentType, null=True)
    instance_id = models.PositiveIntegerField(null=True)
    instance_object = generic.GenericForeignKey('instance_type', 'instance_id')    

    to = models.EmailField()
    subject = models.CharField(max_length=100)
    body = models.TextField(max_length=100)

    def set_template(self, template):
        self.template = template
        if not "\n" in self.template.strip() and ".html" in self.template:
            t = loader.get_template(self.template)
        else:    
            t = Template(self.template)
        self.body = t.render(Context({'instance': self.instance_object}))
        self.save()

    def is_suscribed(self):
        if self.communication_id:
            sus = self.communication.suscriptions.filter(user__email=self.to)
            if not sus:
                return True
            else:
                return sus[0].active
        else:
            return True
        
    def send(self):
        print settings.SERVER_EMAIL, self.to
        email = mail.EmailMessage(self.subject, self.body, from_email=settings.SERVER_EMAIL, to=[self.to])
        email.content_subtype = "html"
        email.send()
        self.sent = True
        self.save()


class Suscription(models.Model):
    user = models.ForeignKey(User, related_name="suscriptions")
    communication = models.ForeignKey(Communication, related_name="suscriptions")
    active = models.BooleanField(default=True)

